package som.simon.reactor;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.util.context.Context;

import java.time.Duration;

public class ContextMain {


    // assuming TL is known to Context-Propagation as key TLKEY.
    static final ThreadLocal<String> TL = new ThreadLocal<>();
    private static final String TL_KEY = "TL_KEY";

    public static void main(String[] args) {

        Flux.range(1, 10)
                .transformDeferredContextual((flux, ctx) -> {
                    System.out.println("flux = " + flux);
                    System.out.println("ctx = " + ctx);
                    return flux.map(ix -> ctx.get("prefix") + "" + SimonUtil.format(ix));
                })
                .contextWrite(Context.of("prefix", "NO."))
                .subscribe(v -> System.out.println("v = " + v));
        
        System.out.println("---------------------------------");

        TL.set("HELLO");

        String result = Mono.deferContextual(ctx ->
                        Mono.delay(Duration.ofSeconds(1))
                                // we're now in another thread, TL is not explicitly set
                                .map(v -> "delayed ctx[" + TL_KEY + "]=" + ctx.getOrDefault(TL_KEY, "not found") + ", TL=" + TL.get()))
                .contextWrite(ctx -> ctx.put(TL_KEY, "HELLO"))
                .block();
                // returns "delayed ctx[TLKEY]=HELLO, TL=null" in default mode
                // returns "delayed ctx[TLKEY]=HELLO, TL=HELLO" in automatic mode

        System.out.println(result);

        System.out.println("---------------------------------");

        TL.set("HELLO");

        String res = Mono.deferContextual(ctx ->
                        Mono.delay(Duration.ofSeconds(1))
                                // we're now in another thread, TL is not explicitly set
                                .map(v -> "delayed ctx[" + TL_KEY + "]=" + ctx.getOrDefault(TL_KEY, "not found") + ", TL=" + TL.get()))
                .contextCapture()
                .block();
                // returns "delayed ctx[TLKEY]=HELLO, TL=null" in default mode
                // returns "delayed ctx[TLKEY]=HELLO, TL=HELLO" in automatic mode

        System.out.println(res);

    }

    /**
     * flux = FluxRange
     * ctx = Context1{prefix=NO.}
     * v = NO.0000001
     * v = NO.0000002
     * v = NO.0000003
     * v = NO.0000004
     * v = NO.0000005
     * v = NO.0000006
     * v = NO.0000007
     * v = NO.0000008
     * v = NO.0000009
     * v = NO.0000010
     */

}
